package com.njitzx.service.impl;

import com.njitzx.constant.UserConstant;
import com.njitzx.entity.dto.LoginDTO;
import com.njitzx.entity.po.User;
import com.njitzx.entity.vo.CodeVO;
import com.njitzx.entity.vo.LoginVO;
import com.njitzx.entity.vo.UserVO;
import com.njitzx.exception.LoginErrorException;
import com.njitzx.mapper.LoginMapper;
import com.njitzx.properties.JwtProperties;
import com.njitzx.service.LoginService;
import com.njitzx.util.JwtUtil;
import com.njitzx.util.PwdUtil;
import com.njitzx.util.SMSUtil;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.base.Captcha;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    JwtProperties jwtProperties;

    public static final String prefix = "captcha:";  //控制redis里面的层级
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private LoginMapper loginMapper;

    @Override
    public LoginVO login(LoginDTO loginDTO) {
        //前端已经做过密码校验了
        String username = loginDTO.getUsername();
        User user = loginMapper.getByUsername(username);
        if (user == null) {
            throw new LoginErrorException("用户名不存在");
        }
        if (!user.getPassword().equals(PwdUtil.encrypt(loginDTO.getPassword()))) {
            throw new LoginErrorException("密码错误");
        }
        LoginVO vo = new LoginVO();
        BeanUtils.copyProperties(user, vo);
        Map<String, Object> map = new HashMap<>();
        map.put("id", user.getId());
        map.put("username", user.getUsername());
        String token = JwtUtil.createJWT(jwtProperties.getSecret(), jwtProperties.getExpire(), map);
        vo.setToken(token);
        return vo;
    }

    @Override
    public CodeVO getCode() {
        Captcha captcha = new ArithmeticCaptcha(100, 40);
        String code = captcha.text();
        String img = captcha.toBase64();
        String uuid = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(prefix + uuid, code);
        System.out.println(code);

        System.out.println(uuid);
        return new CodeVO(uuid, img);
    }

    @Override
    public LoginVO loginCode(LoginDTO loginDTO) {

        checkCode(loginDTO.getCode(), loginDTO.getUuid());
        //前端已经做过密码校验了
        String username = loginDTO.getUsername();
        User user = loginMapper.getByUsername(username);
        if (user == null) {
            throw new LoginErrorException("用户名不存在");
        }
        if (!user.getPassword().equals(PwdUtil.encrypt(loginDTO.getPassword()))) {
            throw new LoginErrorException("密码错误");
        }
        LoginVO vo = new LoginVO();
        BeanUtils.copyProperties(user, vo);
        Map<String, Object> map = new HashMap<>();
        map.put("id", user.getId());
        map.put("username", user.getUsername());
        String token = JwtUtil.createJWT(jwtProperties.getSecret(), jwtProperties.getExpire(), map);
        vo.setToken(token);
        return vo;
    }

    @Override
    public void setPhoneCode(String phone) {
        String code = String.valueOf((int) ((Math.random() * 10 + 1) * 1000));
        //  用户签名 和 sms
        //模拟阿里云登录
//        SMSUtil.sendMessage(UserConstant.signName,UserConstant.sms,phone,code);
        //存储到redis
        redisTemplate.opsForValue().set(UserConstant.PHONE_CODE + phone, code,3, TimeUnit.MINUTES);
        System.out.println(code);
    }

    @Override
    public LoginVO loginByPhone(LoginDTO loginDTO) {
        //前端已经做过密码校验了
        String phone = loginDTO.getPhone();
        String sms = loginDTO.getSms();
        if (phone == null) {
            throw new LoginErrorException("手机号不能为空");
        }
        if (sms == null) {
            throw new LoginErrorException("验证码不能为空");
        }
        String code = (String) redisTemplate.opsForValue().get(UserConstant.PHONE_CODE + phone);

        if (!code.equals(sms)) {
            throw new LoginErrorException("验证码错误");
        }
        redisTemplate.delete(redisTemplate.keys(UserConstant.PHONE_CODE + phone));
        Map<String, Object> map = new HashMap<>();
        User user = loginMapper.getByPhone(phone);
        map.put("id", user.getId());
        map.put("username", user.getUsername());
        String token = JwtUtil.createJWT(jwtProperties.getSecret(), jwtProperties.getExpire(), map);
        LoginVO vo = new LoginVO();
        BeanUtils.copyProperties(user, vo);
        vo.setToken(token);
        return vo;
    }

    public void checkCode(String code, String uuid) {

        String code1 = (String) redisTemplate.opsForValue().get(prefix + uuid);
        if (code1 == null) {
            throw new LoginErrorException("验证码已过期");
        }
        if (!code1.equals(code)) {
            throw new LoginErrorException("验证码错误");
        }
        redisTemplate.delete(prefix + uuid);
    }
}
